/* let str:string = '你好ts';
let isBeauty:boolean = true; */

// any 类型 这个变量可以存储任意的值
/* let a:any = '哈哈哈';
a = 100;
a = [1,2,3,4]; */
// 基础数据类型有
/* 
  string number boolean null undefined any unknown void(定义函数返回值 代表函数没有返回值)
*/

/* // ts中的数组  每个值得类型必须一样
// 直接定义类型
const arr: number[] = [1,2,3,4];
const arr2: string[] = ['1','2','3','4'];
// 泛型定义数组
const arr3: Array<number> = [1,2,34,5]; */

// 元组  理解这是js 中混合数组  数组中每个值得类型可以不一样
// const tuple: [string,number, boolean] = ['aaa', 10, true];


// ts中定义函数
/* function fn(a:number, b: number):void{
  return a+b;
} */
/* const fn = (a: number, b: number): number => {
  return a + b;
}
fn(10, 20) */

// 函数可选参数 一定要传给是最后一个参数
/* function fn(a:number, b?: number, c:number): number{
  console.log(a,b, c);
  
  return 10;
} */
/* 
// 默认值 可以不是最后一个参数，传参使用 undefined占位

function fn(a:string, b:number = 10, c:number):void{
  console.log(a);
  console.log(b);
  console.log(c);
}

fn('哈哈',undefined, 20); */


// 接口 interface
/* 
  专门用来描述 对象的类型结构 可以理解自定义一个类型
  也可以用来描述一个函数的结构
  建议接口命名使用 大驼峰
*/

/* interface PersonType{
  name: string;
  age: number;
  // 可选参数
  gender?: string,
  readonly id: number
}

const obj: PersonType= {
  id: 100,
  name:"小明",
  age: 18,
  // gender: 0
}

obj.name = "小红";
obj.id = 12345678; */

// 接口描述函数的结构
/* interface FnType {
  (a: number, b: string, c?: number): number
}

const fn: FnType = (a: string, b: string, c?:number):void => {
  console.log(a);
  console.log(b);
  console.log(c);
} */

// ts类
/* class Person{
  // 在外部提前定义类型
  name: string;
  age: number;
  constructor(name:string, age:number){
    this.name = name;
    this.age = age;
  };
  act(){
    console.log(this.name+'爱睡觉');
    
  }
} */

// m枚举描述某个事物固定值，使用时只能使用枚举中的一个值  必须使用场景
/* 
  天 白天黑天
  性别  男 女
  星期 七天 星期1 星期天
*/
/* enum Direction {
  north,
  south,
  east,
  west
}; 
// 直接获取枚举的值 得到的是下标
console.log(Direction.north);
// 通过下标反向映射
console.log(Direction[0]); //  */
/* 
// 手动赋值 赋值后不能通过下标获取
enum Direction {
  north = "北",
  south="南",
  east="东",
  west="西"
};

console.log(Direction.north); */

/* 
  类型推论
  TypeScript里，在有些没有明确指出类型的地方，类型推论会**帮助提供类型**。

  这种推断发生在初始化变量和成员，设置默认参数值和决定函数返回值时。
*/

/* 
// 推论a类型是 number
let a = 10;
a = '你好世界'; */
/* 
// 如果只声明不赋值 推论成any类型
let b;
b = 10;
b = '哈哈哈';
b = [1,2,3,4]; */

// 函数形参 通过 默认值 做类型推论
/* function fn(a=10){
  return a;
}

fn('哈哈哈')
 */
// 函数返回值 类型也可以不定义 直接根据返回值得类型做推论


// 联合类型 一个变量 类型可以是多种
// let a: string|number = 10;
// a = '哈哈哈';


// 联合类型类型保护
/* 
  ts如果是联合类型，不管使用 联合类型任意一个类型的api ts都会报错
  提示开发者， ts并不知道，开发者后续 到底传的是什么类型的值
*/
/* function fn(str: string|number){
  // console.log(str.length);
  console.log(str.toFixed(2));
  
} */

// 使用 类型 断言 解决联合类型 类型保护
/* 
  告诉ts 放心我知道我在干啥，我变量断言成number, 告诉ts 我使用时 一定会传number
*/

/* function fn(str: string|number){

  const str2 = str as string;
  if (str2.length !== undefined) {
    console.log(str2.length);
  } else {
    const num = str as number;
    console.log(num.toFixed(2));
  }
  
} */

// 泛型
/* 
  值可以定义变量来存储

  同样的？ 不知道类型一个数据类型 能不能也定义一个变量 存储
  
*/


/* // 函数定义时 使用<> 定义类型变量
function fn<T>(a:T):T{
  return a;
}
// 调用函数 使用 <> 给 未知类型赋值
fn<string>('哈哈');

const arr:Array<number> = [1,2,3,4]; */


/* import type {Type1} from './type'

const obj: Type1 = {
  name: "小明"
} */

// 类型
// 接口的值可以直接定义
/* const obj: {a: number,b: string} = {
  a: 10,
  b: '哈哈哈'
} */

// 类型别名
/* type Name = string;
let a: Name = '哈哈哈';
a = 23456789 */

type Person = {
  name: string,
  age: 18
}
const p1: Person = {
  name:'小明呢',
  age: 18
}